package com.yfree.datebase;

import android.app.Application;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;

import com.google.gson.Gson;
import com.yfree.YConfig;

import org.json.JSONObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author YangZhe 用于操作本地数据库的类
 */
public class YDBOperater {
    private static Gson gson = new Gson();

    /**
     * 执行SQL语句
     */
    public static boolean exec(Context context, String sql, Object... params) {
        boolean isSuccess;
        YDBHelper dbHelper = getDB(context);
        SQLiteDatabase database = null;
        try {
            database = dbHelper.getReadableDatabase();
            database.execSQL(sql, params);
            isSuccess = true;
        } catch (Exception e) {
            isSuccess = false;
        } finally {
            if (database != null)
                database.close();
            dbHelper.close();
        }
        return isSuccess;
    }

    /**
     * 查询SQL语句
     */
    public static <T> ArrayList<T> query(Context context, Class<T> classOfT, String sql, String... params) {
        ArrayList<T> resultSet = new ArrayList<>();
        YDBHelper dbHelper = getDB(context);
        SQLiteDatabase database = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        try {
            cursor = database.rawQuery(sql, params);
            while (cursor.moveToNext()) {
                Map<String, String> result = new HashMap<>();
                for (String columnName : cursor.getColumnNames())
                    result.put(columnName, cursor.getString(cursor.getColumnIndex(columnName)));
                resultSet.add(gson.fromJson(new JSONObject(result).toString(), classOfT));
            }
        } catch (Exception ignored) {
        } finally {
            if (cursor != null) cursor.close();
            database.close();
            dbHelper.close();
        }
        return resultSet;
    }

    public static YDBHelper getDB(Context context) {
        return YDBHelper.getInstance(context, YConfig.dbName, YConfig.dbVersion);
    }

    public static <T> ArrayList<T> querySQLFromFile(String path, Class<T> classOfT, String sql, String... params) {
        ArrayList<T> resultSet = new ArrayList<>();
        SQLiteDatabase database = null;
        Cursor cursor = null;
        try {
            database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
            cursor = database.rawQuery(sql, params);
            while (cursor.moveToNext()) {
                Map<String, String> result = new HashMap<>();
                for (String columnName : cursor.getColumnNames())
                    result.put(columnName, cursor.getString(cursor.getColumnIndex(columnName)));
                resultSet.add(gson.fromJson(new JSONObject(result).toString(), classOfT));
            }
        } catch (Exception ignored) {
        } finally {
            if (cursor != null) cursor.close();
            if (database != null) database.close();
        }
        return resultSet;
    }

    /**
     * 拷贝数据库到sd卡
     *
     * @deprecated <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     */
    public static void copyDataBaseToSD(Application application, String dbName, String outDBName) {
        if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            return;
        }
        File dbFile = new File(application.getDatabasePath(dbName) + ".db");
        File file = new File(Environment.getExternalStorageDirectory(), outDBName + ".db");

        FileChannel inChannel = null, outChannel = null;

        try {
            file.createNewFile();
            inChannel = new FileInputStream(dbFile).getChannel();
            outChannel = new FileOutputStream(file).getChannel();
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } catch (Exception e) {
        } finally {
            try {
                if (inChannel != null) {
                    inChannel.close();
                    inChannel = null;
                }
                if (outChannel != null) {
                    outChannel.close();
                    outChannel = null;
                }
            } catch (IOException e) {
            }
        }
    }
}
